
// http://www.banxue.fun:8084/NewHtjApi?orgCode=2323342709200654133641445833515018164733504318235621445141374539
// src/public/utils/metalUtil.js
let instance = null;

export class MetalUtil {
  constructor() {
    if (instance) {
      return instance;
    }

    instance = this;

    // Fixed URL for all subscriptions
    this.fixedUrl = 'http://www.banxue.fun:8084/NewHtjApi?orgCode=2323342709200654133641445833515018164733504318235621445141374539';
    this.subscribers = []; // Changed from Map to Array
    this.intervalId = null;
    this.pollingInterval = 1000*60*10;  // 10分钟刷新一次
    this.latestData = null;    // 最近一次获取的数据

    return this;
  }

  /**
   * Subscribe to data polling
   * @param {Function} callback - Function to call when data is received (also used as identifier)
   */
  subscribe(callback) {
    // Check if callback is already subscribed to avoid duplicates
    if (!this.subscribers.includes(callback)) {
      this.subscribers.push(callback);
    }

    // If this is the first subscriber, start polling
    if (this.subscribers.length === 1) {
      this.startPolling();
    }
    // If we already have data, immediately call the callback with the latest data
    if (this.latestData !== null) {
      try {
        callback(this.latestData, null);
      } catch (error) {
        console.error('Error in callback:', error);
      }
    }
  }

  /**
   * Unsubscribe from data polling
   * @param {Function} callback - The callback function to remove
   */
  unsubscribe(callback) {
    const index = this.subscribers.indexOf(callback);
    if (index > -1) {
      this.subscribers.splice(index, 1);
    }

    if (this.subscribers.length === 0) {
      this.stopPolling();
    }
  }

  /**
   * Start polling data from the fixed URL
   */
  startPolling() {
    if (this.intervalId) return;

    // 首次调用，直接获取数据
    this._fetchMetalPrice();

    this.intervalId = setInterval(async () => {
      this._fetchMetalPrice();
    }, this.pollingInterval);
  }

  async _fetchMetalPrice() {
    try {
      const response = await fetch(this.fixedUrl);
      if (response.ok) {
        const data = await response.json();

        this.latestData = data;



        for (let i = this.subscribers.length - 1; i >= 0; i--) {
          const callback = this.subscribers[i];
          try {
            callback(data, null);
          } catch (callbackError) {
            console.error('Error in callback and remove the callback:', callbackError);
            // Remove the problematic callback
            this.subscribers.splice(i, 1);
          }
        }

        // 如果订阅者列表为空，则停止轮询
        if(this.subscribers.length === 0){
          this.stopPolling();
        }

      } else {
        const error = new Error(`HTTP Error: ${response.status}`);
        // Notify all subscribers about the error
        console.error('Error in fetching data:', error);
      }
    } catch (error) {
      // Notify all subscribers about the network error
      for (const callback of this.subscribers) {
        try {
          callback(null, error);
        } catch (error) {
          console.error('Error in callback:', error);
        }
      }
    }
  }

  /**
   * Stop the polling interval
   */
  stopPolling() {
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
  }

  /**
   * Update polling interval
   * @param {number} interval - New interval in milliseconds
   */
  setPollingInterval(interval) {
    this.pollingInterval = interval;

    if (this.intervalId) {
      this.stopPolling();
      this.startPolling();
    }
  }

  /**
   * Update the fixed URL
   * @param {string} url - New fixed URL
   */
  setFixedUrl(url) {
    this.fixedUrl = url;
  }

  /**
   * Get the singleton instance
   * @returns {MetalUtil}
   */
  static getInstance() {
    if (!instance) {
      instance = new MetalUtil();
    }
    return instance;
  }
}